/* 
 * File:   fleets.h
 * Author: cow
 *
 * Created on May 27, 2011, 5:30 PM
 */

#ifndef FLEETS_H
#define	FLEETS_H

//includes-----------------------------------------------------------
#include <map>
#include <vector>
//defines------------------------------------------------------------
namespace combat{
enum bateryType{
    foreward = 0,
    broadside,
    rear,
    artilery,
	maxBat
};
enum direction{
    up = 0,
    left,
    right,
    down
};
enum formation{
	standard = 0,
	spindle,
	broad,
	Aril,
	Siege
};
}
//prototypes---------------------------------------------------------
namespace combat {
class combatant;
class officer;
class ship;
class shipHolder;
class strikeGroup;
class fleet;

class batery;
class bullet;
class voley;
}
//dependant includes-------------------------------------------------
#include "../Main.h"

//definitions--------------------------------------------------------
namespace combat {
//bullet+++++++++++
class bullet{
public:
	bullet(int d, int a);
	int dam();
	int acc();
	bool operator==(bullet &b);
private:
	int damage, accuracy;
};
//battery++++++++++
class battery{
public:
	//constructor------------
	battery(int d, int a, int minr, int maxr, int acost, int scost);
	//access-----------------
	bullet* shoot(int* ap, int* salvos, int range);
	//manips-----------------
private:
	bullet b;
	int apc, sc;
	int maxRange, minRange;
};
//voley++++++++++++
//combatant++++++++
class combatant : public mapdata::placeable{
public:
	static int range(int sx, int sy, int dx, int dy);
	static direction relation(int sx, int sy, int dx, int dy);
	static void shoot(combatant* src, combatant* targ);
	virtual void shoot(combatant* targ) = 0;
	virtual voley* shoot() = 0;
	virtual void damage(voley* v) = 0;
	virtual bool isDead() = 0;
	virtual void onDeath() = 0;
};
//officer++++++++++
class officer {
public:
	//constructors------
	officer(int pow, int spd, int cohes, string name);
	~officer();
	//access------------
	int gLevel();
	int gPow();
	int gSpd();
	int gCohes();
	//manips------------
	int sLevel(int ep);
private:
	string name;
	int pow, spd, cohes;
	int level, exp;
};
//ship+++++++++++++
class ship {
public:
	//constructors------
	ship(int arm, int shd, int eva, int spd, string name);
	ship(ship* u);
	~ship();
	void addBatery(bateryType btp, int dam = 0, int acc = 50,
		int mnr = 0, int mxr = 0, int ap = 1);
	//access------------
	bullet* gbattery(bateryType btp) {
		return batery[btp];
	}
	//manips------------
	bullet* shoot(bateryType btp);
	int dead(voley* vol, bool shield);
	//stats-------------
	int arm();
	int shd();
	int eva();
	int spd();
protected:
private:
	string name;
	int armor;
	int shield;
	int evasion;
	int speed;
	//fore, aft, broad, artilery
	bullet *batery[maxBat];
};
//shipHolder+++++++
class shipHolder {
	class iterator {
	public:
		//constructor---
		iterator(map<ship*, int>* mp);
		~iterator();
		void operator++(int);
		void operator--(int);
		void operator*();
		void operator->();
	private:
		map<ship*, int>::iterator me;
	};
public:
	//constructor-------
	shipHolder();
	~shipHolder();
	//access------------
	virtual void add(ship* s, int);
	virtual void remove(ship*, int);
	virtual int get(ship* s);
	iterator gIter();
	//manips------------
private:
	map<ship*, int> shipList;
};
//strikeGroup++++++
class strikeGroup : public mapdata::moveable, public combatant, public shipHolder {
public:
	//constructor-------
	strikeGroup();
	strikeGroup(mapdata::maprep* mr);
	~strikeGroup();
	void onDeath();
	//access------------
	virtual voley* shoot();
	int gId();
	int gOwner();
	bool isDead();
	//manips------------
	void addTo(fleet* parent);
	void addTo(officer* off);
	virtual void damage(voley* v);
	virtual void move(int x, int y);
	//buffs-------------
	void buff(int pow, int spd, int cohes);
	void debuf(int pow, int spd, int cohes);
private:
	fleet* parent;
	officer* command;
	int owner, id;
};
//fleet++++++++++++
class fleet : public shipHolder {
	class iterator {
	public:
		iterator(vector<strikeGroup*>* sgv);
		~iterator();
		void operator++(int);
		void operator--(int);
		void operator*();
		void operator->();
	private:
		vector<strikeGroup*>::iterator itr;
	};
public:
	fleet(string _name, strikeGroup* _flag);
	int add(strikeGroup* sg);
	void remove(strikeGroup* sg);
	void setFlag(int id);
private:
	string name;
	strikeGroup* flag;
};
}
#endif	/* FLEETS_H */

